﻿using System.Linq;
using System.Text.RegularExpressions;
using PetaPoco.Core;
using PetaPoco.Utilities;

namespace PetaPoco
{
    static class IProviderExtensions
    {

        //public static string BuildPageQuery(this IProvider provider, long skip, long take, SQLParts parts, ref object[] args, string primaryKey)
        //{
        //    var helper = (PagingHelper)provider.PagingUtility;
        //    // when the query does not contain an "order by", it is very slow
        //    if (helper.SimpleRegexOrderBy.IsMatch(parts.SqlSelectRemoved))
        //    {
        //        var m = helper.SimpleRegexOrderBy.Match(parts.SqlSelectRemoved);
        //        if (m.Success)
        //        {
        //            var g = m.Groups[0];
        //            parts.SqlSelectRemoved = parts.SqlSelectRemoved.Substring(0, g.Index);
        //        }
        //    }

        //    if (helper.RegexDistinct.IsMatch(parts.SqlSelectRemoved))
        //        parts.SqlSelectRemoved = "peta_inner.* FROM (SELECT " + parts.SqlSelectRemoved + ") peta_inner";

        //    //var sqlPage =
        //    //    $"SELECT * FROM (SELECT ROW_NUMBER() OVER ({parts.SqlOrderBy ?? "ORDER BY (SELECT NULL)"}) peta_rn, {parts.SqlSelectRemoved}) peta_paged WHERE peta_rn > @{args.Length} AND peta_rn <= @{args.Length + 1}";

        //    if (primaryKey.Contains<char>('.') && !primaryKey.EndsWith("."))
        //        primaryKey = primaryKey.Substring(primaryKey.LastIndexOf(".") + 1);//移除表名

        //    var sqlPage = string.IsNullOrEmpty(primaryKey) ? string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER ({0}) peta_rn, {1}) peta_paged WHERE peta_rn>@{2} AND peta_rn<=@{3}", parts.SqlOrderBy == null ? "ORDER BY (SELECT NULL)" : parts.SqlOrderBy, parts.SqlSelectRemoved, args.Length, args.Length + 1)
        //        : string.Format("SELECT peta_paged.{4} FROM (SELECT ROW_NUMBER() OVER ({0}) peta_rn, {1}) peta_paged WHERE peta_rn>@{2} AND peta_rn<=@{3}",
        //                            string.IsNullOrEmpty(parts.SqlOrderBy) ? "ORDER BY (SELECT NULL)" : parts.SqlOrderBy, parts.SqlSelectRemoved, args.Length, args.Length + 1, primaryKey);

        //    args = args.Concat(new object[] { skip, skip + take }).ToArray();
        //    return sqlPage;
        //}

        public static string AddSelectClause<T>(this IProvider provider, string sql, IMapper defaultMapper, string primaryKey = null)
        {
            if (sql.StartsWith(";"))
                return sql.Substring(1);

            if (!rxSelect.IsMatch(sql))
            {
                var pd = PocoData.ForType(typeof(T), defaultMapper);
                var tableName = provider.EscapeTableName(pd.TableInfo.TableName);
                string cols = string.IsNullOrEmpty(primaryKey) ? (pd.Columns.Count != 0 ? string.Join(", ", (from c in pd.QueryColumns select tableName + "." + provider.EscapeSqlIdentifier(c)).ToArray()) : "NULL")
                    : primaryKey;
                if (!rxFrom.IsMatch(sql))
                    sql = string.Format("SELECT {0} FROM {1} {2}", cols, tableName, sql);
                else
                    sql = string.Format("SELECT {0} {1}", cols, sql);
            }
            return sql;
        }

        static Regex rxSelect = new Regex(@"\A\s*(SELECT|EXECUTE|CALL)\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
        static Regex rxFrom = new Regex(@"\A\s*FROM\s", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Multiline);
    }
}
